\documentclass{ctexart}
\usepackage{ctex}
\usepackage{listings}
\title{计算器的实现}
\author{李佳茗 \\ 统计学　3210104617}

\begin{document}
\maketitle
\section{设计思路}
\subsection{框架}
I. 将input.txt文件中每一行的中缀表达式调用\lstinline[language = c++]{postfix(string line)}函数转化为后缀表达式 \par
II. 调用\lstinline[language = c++]{postfix_eval_exp(const string& postfix)}函数通过堆栈(stack)和队列(quene)计算后缀表达式并将结果返回 \par
III. 若\lstinline[language = c++]{_err_exp()}函数检测到异常时，返回“Error.” \par

\subsection{主函数}
I.   以只读形式打开并读取 input.txt 文件，存储每一行的字符串\par
II.  输出 ouput.txt 文件，以只写方式打开文件并在打开文件之前清空文件内容\par
III. 检查文件正常打开后，从输入流 fin 中不断读取一行数据，并将其存储在字符串变量 line 中\par
IV.  调用 \lstinline[language = c++]{postfix} 函数，将字符串 line 转为后缀表达式，并将其存储在 \lstinline[language = c++]{postfix_exp} 中\par
V.   调用 \lstinline[language = c++]{postfix_eval_exp} 函数，计算后缀表达式，并返回结果，将结果输出到输出流 fout 中\par
VI.  若检测到异常，则输出“Error."\par

\subsection{\lstinline[language = c++]{postfix} 函数：将中缀表达式变为后缀表达式}
\subsubsection{逐个存储 line 中的元素}
I. 若遇到回车，则结束\par
II. 若遇到制表符和空格，则跳过\par
III. 若遇到数字，则直接输出\par
IV. 若遇到小数点，则只允许一个小数点\par
V. 若遇到左括号，则只入栈一个左括号（只考虑小括号）\par
VI. 若遇到右括号，先判断是否有左括号匹配，若有，则运算'()'内的数，并将小括号都推出栈（未考虑空括号与复合括号）\par
VII. 若遇到加/减号，清空全部运算符, 直到遇到左括号或者空栈\par
VIII. 若遇到乘/除号，只进行同等优先级的运算\par
IX. 若栈中仍剩余运算符，则依次弹出并入栈\par
\subsubsection{将其存入\lstinline[language = c++]{stringstream ss}中}
I. 如果是小数部分，直接输出数字 \par
II. 如果是整数部分，先输出空格，再输出数字\par
III. 如果是小数点，末尾再输出一个空格，point = true，遇到其他字符则说明小数部分结束\par
IV. 如果是运算符，则直接输出\par

\subsection{ \lstinline[language = c++]{postfix_eval_exp} 函数：计算后缀表达式 }
从输入流 ss 中连续读取字符串，并将每个读取的字符串存储到名为 element 的变量中：\par
I. 若读入为整数，则将其转化为浮点数，并存入栈中\par
II. 若读入为小数部分，则将将整数部分与小数部分合并，并将新得到的数推入栈（只考虑了整数位为个位数的情况）\par
III. 若读入为运算符，则取栈顶的两个元素进行相应的运算，并将运算结果存入栈中\par
直至栈中只剩一个元素，即为最终计算结果。

\subsection{\lstinline[language = c++]{_err_exp} 函数：处理异常}

定义全局变量 error = false，若遇到异常则变为true。

\section{测试说明}
I. input.txt, 纯文本文件, 存放用于测试的字符串；每一行都是一个独立的输入字符\par
II. output.txt文件中。\par
III. 用户输入为一个字符串, 忽略其中不属于数字, 小数点, +, -, *, /, (,) 
和空格以外的字符。将剩下的符号, 识别成浮点数和运算符；
如果这些浮点数(包括整数)和运算符组成合法的中缀表达式, 输出其运算
结果；
如果无法组成合法的中缀表达式, 输出"Error."\par
\subsection{1.2sdf3!!3 − 0.23}
中缀表达式：$1.233-0.23$\par
后缀表达式：$ 1 . 233   0 . 23 - $\par
输出结果：1.003\par
\subsection{1t.y21 * (3RR-4T + 1s.s00)}
中缀表达式：$1.21*(3-4+1.00)$\par
后缀表达式：$ 1 . 21   3 4 - 1 . 00   + *$\par
输出结果：0
\subsection{1((2}
只有两个左括号，没有右括号，非法！\par
输出结果：Error.\par
\subsection{1.22.3+1}
同一个出现了两个小数点，非法！\par
输出结果：Error.\par
\end{document}